﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Metadata.Entity;

namespace T.FAS.Runtime.Metadata.Entity.DataModel
{
    public class TAction : ICloneable, IRefSchemaDetail
    {
        /// <summary>
        /// 主键id
        /// </summary>
        public string ID { get; set; }

        /// <summary>
        /// 所属状态机ID
        /// </summary>
        [JsonIgnore]
        public string StateMachineID { get; set; }

        /// <summary>
        /// 动作所属的状态变换ID
        /// </summary>
        [JsonIgnore]
        public string TransitionID { get; set; }

        /// <summary>
        /// 动作key
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// 动作名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 动作描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 动作作用的CDO的主节点的Element.Alias
        /// </summary>
        public string Target { get; set; }

        /// <summary>
        /// 0:System, 1:Expression
        /// </summary>
        public ActionType ActionType { get; set; }

        /// <summary>
        /// 动作执行时机
        /// </summary>
        public ActionExecuteTiming ActionExecuteTiming { get; set; }

        /// <summary>
        /// RuleType:System时，RuleInfo存储系统预置的默认动作标识（Default,Copy,Empty）;
        /// RuleType:Expression时，RuleInfo存储表达式规则的内容，该表达式执行结果返回TRecord类型的值
        /// </summary>
        public string ActionInfo { get; set; }

        /// <summary>
        /// 当ActionType:Expression时，存储表达式的Json内容，供表达式SDK使用
        /// </summary>
        public string ActionInfoJson { get; set; }

        /// <summary>
        /// 前置条件表达式参数Json内容，用不到
        /// </summary>
        [JsonIgnore]
        public string ParameterString { get; set; }

        /// <summary>
        /// 排序
        /// </summary>
        public int Sort { get; set; }

        private Dictionary<string, object> paramters;

        /// <summary>
        /// Action参数信息
        /// </summary>
        public Dictionary<string, object> Paramters
        {
            get
            {
                //获取参数时，反序列化ParameterString中的参数Json
                if (paramters == null && !string.IsNullOrEmpty(ParameterString))
                {
                    try
                    {
                        paramters = JsonConvert.DeserializeObject<Dictionary<string, object>>(ParameterString);
                    }
                    catch (Exception e)
                    {
                        throw new FasException(DataModelErrorCode.SM.SerializeError, $"状态机:{StateMachineID}的动作:{this.Key}入参Json:{ParameterString}反序列化失败，请检查", e);
                    }
                }
                return paramters;
            }
            set
            {
                if (value != null)
                {
                    paramters = value;
                    ParameterString = JsonConvert.SerializeObject(value);
                }
            }
        }

        /// <summary>
        /// 备用字段
        /// </summary>
        [JsonIgnore]
        public string Ext1 { get; set; }

        /// <summary>
        /// 备用字段
        /// </summary>
        [JsonIgnore]
        public string Ext2 { get; set; }

        /// <summary>
        /// 备用字段
        /// </summary>
        [JsonIgnore]
        public string Ext3 { get; set; }

        /// <summary>
        /// 创建人
        /// </summary>
        [JsonIgnore]
        public string Creator { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>       
        [JsonIgnore]
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        [JsonIgnore]
        public string LastModifier { get; set; }

        /// <summary>
        /// 最后修改时间
        /// </summary>        
        [JsonIgnore]
        public DateTime LastModifyTime { get; set; }

        public object Clone()
        {
            return this.MemberwiseClone();
        }

        public string GetRefSchemaExpr(IMetaDataContent metaData)
        {
            if (metaData is StateMachineMetadata sm)
            {
                try
                {
                    string prefix = sm.GetTopRefSchemaExpr();
                    string actionConst = nameof(TTransition.Actions);
                    string ruleConst = nameof(TState.Rules);
                    string eventConst = nameof(StateMachineMetadata.Events);
                    TTransition trans;
                    if (string.IsNullOrEmpty(this.TransitionID))
                    {
                        trans = sm.Transitions.FirstOrDefault(s => s.Actions.Exists(r => r.ID == this.ID));
                    }
                    else
                    {
                        trans = sm.Transitions.FirstOrDefault(s => s.ID == this.TransitionID);
                    }
                    var even = sm.Events.FirstOrDefault(e => e.ID == trans.EventID);
                    string eventPrefix = $"{prefix}.{eventConst}.{even.Key}";
                    var result = $"{eventPrefix}.{actionConst}.{this.ID.Replace("-", "")}.{RefSchemaExprUtil.Const.Text}";
                    return result;
                }
                catch (Exception e)
                {
                }
            }
            return null;
        }
    }

    public enum ActionType
    {
        System,
        Expression
    }

    public enum ActionExecuteTiming
    {
        StateChanging,
        BeforeSave,
        AfterSave,
    }
}
